Fab лаборатория – это открытая небольшая
мастерская, где можно создать или изготовить практически все, что захотите, в
основном с помощью инструментов с компьютерным управлением, таких как лазерный
резак или 3D-принтер. Недавно фабрика FAU получила фрезерный станок с ЧПУ.
Используя фрезерный станок, Вы можете резать или удалять материал с поверхности
заготовки разными инструментами. Он управляется компьютерной программой.
Иногда мне было интересно,
что произойдет, если несколько заготовок разной формы будут отправлены через
одну программу фрезерования. Для упрощения предположим, что у нас есть только
двумерные заготовки без отверстий. Программа фрезерования состоит из нескольких
шагов. Каждый шаг описывает, где фрезерный станок должен удалить материал (с
помощью различных инструментов) с верхней части поверхности.
Вход.
Первая строка состоит из двух целых чисел w и s (1 ≤ w, s ≤ 104), где w количество деталей, а s количество шагов в программе фрезерования. Следующая строка состоит из двух
целых чисел x и y (1 ≤ x, y ≤ 100), где x –
ширина, а y – максимально возможная высота заготовки.
Каждая из следующих w строк описывает одну деталь. Описание каждой детали состоит из x целых неотрицательных чисел, определяющих высоту поверхности в этом
столбце.
Каждая из следующих s строк описывает один шаг фрезерования в программе. Описание каждого
шага фрезерования состоит из x целых неотрицательных чисел si (0 ≤ si ≤ y),
определяющих количество отрезанной поверхности. каждый столбец (относительно высоты
области фрезерования, т.е. y, а
не относительно верха заготовки). Смотрите рисунок.
Выход.
Для каждой заготовки выведите одну строку, содержащую x целых чисел, определяющих оставшуюся высоту поверхности (в том же
порядке, как и во входных данных).
Рисунок. Вторая деталь в первом примере: исходная деталь с последующим
фрезерованием в каждом столбце – значение в программе фрезерования определяет
вертикальное положение фрезерной головки.
Пример входа 1 |
Пример выхода 1 |
2 1 3 4 4 4 4 4 2 3 2 3 0 |
2 1 4 2 1 3 |
|
|
Пример входа 2 |
Пример выхода 2 |
1 3 10 100 11 22 33 44 55 66 77 88 99 100 1 100 1 100 1 100 1 100 1 100 58 58 58 58 58 58 58 58 58 58 42 42 42 42 42 42 42 42 66 42 |
11 0 33 0 42 0 42 0 34 0 |
математика
Анализ
алгоритма
Программа фрезерования состоит из s шагов.
Пусть на i-ом (1 ≤ i ≤ s) шаге фрезерования от поверхности
в столбце j (1 ≤ j ≤ x) будет
отрезано mij. Тогда очевидно, что суммарно в столбце j будет
отрезано max(m1j, m2j, …, msj). Схемой фрезерования будем называть набор целых чисел (cuts1, cuts2, …, cutsx), где
cutsj = max(m1j, m2j, …, msj), 1 ≤ j ≤ x
Одна и
та же схема фрезерования применяется ко всем w
деталям. Вычислив значения cutsj (1 ≤ j ≤ x),
применим схему фрезерования к каждой детали.
Реализация
алгоритма
Объявим рабочие массивы. Информация
о деталях будет храниться в массиве detail. Схему фрезерования будем хранить в массиве cuts.
int
detail[10001][101], cuts[101];
Читаем входные данные.
scanf("%d %d %d %d", &w, &s,
&x, &y);
Читаем информацию о w деталях.
for (i = 0;
i < w; i++)
for (j = 0;
j < x; j++)
scanf("%d", &detail[i][j]);
Читаем и обрабатываем s шагов в программе фрезерования. cuts[j] будет
содержать самый глубокий вырез в позиции j.
for (i = 0;
i < s; i++)
for (j = 0;
j < x; j++)
{
scanf("%d", &val);
if (val > cuts[j]) cuts[j] = val;
}
Максимально возможная высота заготовки равна y. Фрезерная головка в позиции j
опускается на глубину cuts[j].
Следовательно в позиции j от i-ой детали останется высота, равная min(detail[i][j],
y – cuts[j]).
for (i = 0;
i < w; i++)
{
for (j = 0; j < x; j++)
printf("%d ", min(detail[i][j], y - cuts[j]));
printf("\n");
}